home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / SmallTalk / mstbyte.c < prev    next >
C/C++ Source or Header  |  1995-08-25  |  19KB  |  819 lines

  1. /***********************************************************************
  2.  *
  3.  *    Byte code array utility routines.
  4.  *
  5.  ***********************************************************************/
  6.  
  7. /***********************************************************************
  8.  *
  9.  * Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  10.  * Written by Steve Byrne.
  11.  *
  12.  * This file is part of GNU Smalltalk.
  13.  *
  14.  * GNU Smalltalk is free software; you can redistribute it and/or modify it
  15.  * under the terms of the GNU General Public License as published by the Free
  16.  * Software Foundation; either version 1, or (at your option) any later 
  17.  * version.
  18.  * 
  19.  * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  20.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  21.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  22.  * more details.
  23.  * 
  24.  * You should have received a copy of the GNU General Public License along with
  25.  * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  26.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  27.  *
  28.  ***********************************************************************/
  29.  
  30.  
  31. /*
  32.  *    Change Log
  33.  * ============================================================================
  34.  * Author      Date       Change 
  35.  * P.Lecoanet 22 Dec 91   Fixed byteCodeLength failing to return 0
  36.  *
  37.  * sbyrne    20 Apr 90      Added initByteCodes to fix a robustness issue with
  38.  *              the compiler.
  39.  *
  40.  * sbyrne    27 Dec 88      created.
  41.  *
  42.  */
  43.  
  44. #include "mst.h"
  45. #include "mstbyte.h"
  46.  
  47. #define BYTE_CODE_CHUNK_SIZE        64
  48.  
  49. struct ByteCodeArray {
  50.   Byte        *base;        /* base of the byte code array */
  51.   Byte        *ptr;        /* current byte+1 of byte code array */
  52.   int        maxLen;        /* max allocated len of byte code array
  53.                    can be changed as byte code array grows,
  54.                    and is used to tell when to grow the byte
  55.                    code array. */
  56. };
  57.  
  58. ByteCodes        currentByteCodes = nil;
  59.  
  60. static ByteCodes    allocByteCodes();
  61. static void        compileByteCodes(), reallocByteCodes();
  62.  
  63.  
  64. /* These are used to decode special send byte codes. */
  65. static char        *mathMessageName[] = {
  66.   "+",
  67.   "-",
  68.   "<",
  69.   ">",
  70.   "<=",
  71.   ">=",
  72.   "=",
  73.   "~=",
  74.   "*",
  75.   "/",
  76.   "\\",
  77.   "@",
  78.   "bitShift:",
  79.   "//",
  80.   "bitAnd:",
  81.   "bitOr:"
  82. };
  83.  
  84. /* These are the selectors for special case send bytecodes that the compiler 
  85.    generates.  These are used only to print out the generated byte codes. */
  86. static char        *specialMessageName[] = {
  87.   "at:",
  88.   "at:put:",
  89.   "size",
  90.   "next",
  91.   "nextPut:",
  92.   "atEnd",
  93.   "==",
  94.   "class",
  95.   "blockCopy:",
  96.   "value",
  97.   "value:",
  98.   "do:",
  99.   "new",
  100.   "new:",
  101.   "x",
  102.   "y"
  103. };
  104.  
  105. void compileByte(byte)
  106. Byte byte;
  107. {
  108.   if (currentByteCodes == nil) {
  109.     currentByteCodes = allocByteCodes();
  110.   }
  111.  
  112.   if ((currentByteCodes->ptr - currentByteCodes->base)
  113.       >= currentByteCodes->maxLen) {
  114.     reallocByteCodes(currentByteCodes);
  115.   }
  116.  
  117.   *currentByteCodes->ptr++ = byte;
  118. }
  119.  
  120. void compileAndFreeByteCodes(byteCodes)
  121. ByteCodes byteCodes;
  122. {
  123.   compileByteCodes(byteCodes);
  124.   freeByteCodes(byteCodes);
  125. }
  126.  
  127. /*
  128.  *    void initByteCodes()
  129.  *
  130.  * Description
  131.  *
  132.  *    Initialize the byte code system.  Basically used to set the byte code
  133.  *    system to a known state, typically in preparation for compilation.
  134.  *
  135.  */
  136. void initByteCodes()
  137. {
  138.   if (currentByteCodes) {
  139.     free(currentByteCodes);    /* ??? this might lose if trashed. */
  140.     currentByteCodes = nil;
  141.   }
  142. }
  143.  
  144. /*
  145.  *    ByteCodes getByteCodes()
  146.  *
  147.  * Description
  148.  *
  149.  *    Called when byte code compilation is complete, this routine returns the
  150.  *    set of byte codes that were compiled.  Since compilation is complete,
  151.  *    this routine also resets the internal state of the byte code compiler
  152.  *    in preparation for next time.
  153.  *
  154.  * Outputs
  155.  *
  156.  *    A pointer to a byte code array that contains the bytes for the current
  157.  *    compilation.
  158.  */
  159. ByteCodes getByteCodes()
  160. {
  161.   ByteCodes    curByteCodes;
  162.  
  163.   curByteCodes = currentByteCodes;
  164.   currentByteCodes = nil;
  165.  
  166.   return (curByteCodes);
  167. }
  168.  
  169.  
  170. /*
  171.  *    ByteCodes saveByteCodeArray()
  172.  *
  173.  * Description
  174.  *
  175.  *    Called to save the set of byte codes currently being compiled and
  176.  *    prepare for a new compilation of byte codes.  The current set of byte
  177.  *    codes being compiled is returned for the caller to keep and to later
  178.  *    use in a restoreByteCodeArray call.
  179.  *
  180.  * Outputs
  181.  *
  182.  *    A byte code array pointer to the current byte codes.
  183.  */
  184. ByteCodes saveByteCodeArray()
  185. {
  186.   ByteCodes    curByteCodes;
  187.  
  188.   curByteCodes = currentByteCodes;
  189.   currentByteCodes = nil;
  190.  
  191.   return (curByteCodes);
  192. }
  193.  
  194.  
  195. /*
  196.  *    void restoreByteCodeArray(byteCodes)
  197.  *
  198.  * Description
  199.  *
  200.  *    Restores the internal state of the byte code compiler so that it can
  201.  *    continue compiling byte codes into the byte code array "byteCodes",
  202.  *    which should have been returned at some previous point from
  203.  *    saveByteCodeArray().
  204.  *
  205.  * Inputs
  206.  *
  207.  *    byteCodes: 
  208.  *        The byte code array pointer to be restored.  Should have come
  209.  *        from a saveByteCodeArray call.
  210.  *
  211.  */
  212. void restoreByteCodeArray(byteCodes)
  213. ByteCodes byteCodes;
  214. {
  215.   currentByteCodes = byteCodes;
  216. }
  217.  
  218. int byteCodeLength(byteCodes)
  219. ByteCodes byteCodes;
  220. {
  221.   if (byteCodes == nil) {
  222.     return (0);
  223.   }
  224.   return (byteCodes->ptr - byteCodes->base);
  225. }
  226.  
  227.  
  228. /*
  229.  *    int currentByteCodeLength()
  230.  *
  231.  * Description
  232.  *
  233.  *    Return the current number of byte codes that have been compiled.
  234.  *
  235.  * Outputs
  236.  *
  237.  *    Number of byte codes present in the current byte code array right now.
  238.  */
  239. int currentByteCodeLength()
  240. {
  241.   if (currentByteCodes == nil) {
  242.     return (0);
  243.   }
  244.  
  245.   return (currentByteCodes->ptr - currentByteCodes->base);
  246. }
  247.  
  248. int isSimpleReturn(byteCodes)
  249. ByteCodes byteCodes;
  250. {
  251.   Byte        *bytes;
  252.   long        byteCodeLen;
  253.  
  254.   if (byteCodes == nil) {
  255.     return (0);
  256.   }
  257.  
  258.   byteCodeLen = byteCodeLength(byteCodes);
  259.   bytes = byteCodes->base;
  260.  
  261.   /* check for ^self */
  262.   if (byteCodeLen == 1 && bytes[0] == (returnIndexed | receiverIndex)) {
  263.     return (1);
  264.   }
  265.  
  266.   /* check for ^instanceVariable */
  267.   if (byteCodeLen == 2) {
  268.     if ((bytes[0] & ~0x0F) == pushReceiverVariable
  269.     && bytes[1] == returnMethodStackTop) {
  270.       return (((bytes[0] & 0x0F) << 8) | 2);
  271.     }
  272.   } else if (byteCodeLen == 3) {
  273.     if (bytes[0] == pushIndexed
  274.      && (bytes[1] & locationMask) == receiverLocation
  275.      && bytes[2] == returnMethodStackTop) {
  276.       return (((bytes[1] & ~locationMask) << 8) | 2);
  277.     }
  278.   }
  279.  
  280.   return (0);
  281. }
  282.  
  283. void copyByteCodes(dest, byteCodes)
  284. Byte    *dest;
  285. ByteCodes byteCodes;
  286. {
  287.   memcpy(dest, byteCodes->base, byteCodeLength(byteCodes));
  288. }
  289.  
  290. /***********************************************************************
  291.  *
  292.  *    Internal routines.
  293.  *
  294.  ***********************************************************************/
  295.  
  296. static void compileByteCodes(byteCodes)
  297. register ByteCodes byteCodes;
  298. {
  299.   register Byte        *ptr;
  300.  
  301.   for (ptr = byteCodes->base; ptr < byteCodes->ptr; ptr++) {
  302.     compileByte(*ptr);
  303.   }
  304. }
  305.  
  306. static ByteCodes allocByteCodes()
  307. {
  308.   ByteCodes    newByteCodes;
  309.  
  310.   newByteCodes = (ByteCodes)malloc(sizeof(struct ByteCodeArray));
  311.   newByteCodes->base = (Byte *)malloc(BYTE_CODE_CHUNK_SIZE);
  312.   newByteCodes->ptr = newByteCodes->base;
  313.   newByteCodes->maxLen = BYTE_CODE_CHUNK_SIZE;
  314.  
  315.   return (newByteCodes);
  316. }
  317.  
  318. static void reallocByteCodes(byteCodes)
  319. ByteCodes byteCodes;
  320. {
  321.   Byte        *newBytes;
  322.   int        newLen;
  323.  
  324.   if (byteCodes->maxLen != (byteCodes->ptr - byteCodes->base)) {
  325.     errorf("reallocByteCodes called with maxLen != byteCode len");
  326.   }
  327.  
  328.   newLen = byteCodes->maxLen + BYTE_CODE_CHUNK_SIZE;
  329.   newBytes = (Byte *)malloc(newLen);
  330.   memcpy(newBytes, byteCodes->base, byteCodes->maxLen);
  331.   free(byteCodes->base);
  332.  
  333.   byteCodes->base = newBytes;
  334.   byteCodes->ptr = newBytes + byteCodes->maxLen;
  335.   byteCodes->maxLen = newLen;
  336. }
  337.  
  338. void freeByteCodes(byteCodes)
  339. ByteCodes byteCodes;
  340. {
  341.   if (byteCodes != nil) {
  342.     free(byteCodes->base);
  343.     free(byteCodes);
  344.   }
  345. }
  346.  
  347. void printByteCodes(byteCodes, literalVec)
  348. ByteCodes byteCodes;
  349. OOP    literalVec[];
  350. {
  351.   Byte        *b;
  352.   int        ip;
  353.  
  354.   if (byteCodes == nil) {
  355.     return;
  356.   }
  357.  
  358.   for (b = byteCodes->base; b < byteCodes->ptr; b++) {
  359.     ip = b - byteCodes->base;
  360.     printf("%5d:\t", ip);
  361.     printByteCodeName(b, ip, literalVec);
  362.     printf("\n");
  363.     switch (*b) {
  364.     case  0: case  1: case  2: case  3:
  365.     case  4: case  5: case  6: case  7:
  366.     case  8: case  9: case 10: case 11:
  367.     case 12: case 13: case 14: case 15:
  368.       break;
  369.  
  370.     case 16: case 17: case 18: case 19:
  371.     case 20: case 21: case 22: case 23:
  372.     case 24: case 25: case 26: case 27:
  373.     case 28: case 29: case 30: case 31:
  374.       break;
  375.  
  376.     case 32: case 33: case 34: case 35:
  377.     case 36: case 37: case 38: case 39:
  378.     case 40: case 41: case 42: case 43:
  379.     case 44: case 45: case 46: case 47:
  380.     case 48: case 49: case 50: case 51:
  381.     case 52: case 53: case 54: case 55:
  382.     case 56: case 57: case 58: case 59:
  383.     case 60: case 61: case 62: case 63:
  384.       break;
  385.  
  386.     case 64: case 65: case 66: case 67:
  387.     case 68: case 69: case 70: case 71:
  388.     case 72: case 73: case 74: case 75:
  389.     case 76: case 77: case 78: case 79:
  390.     case 80: case 81: case 82: case 83:
  391.     case 84: case 85: case 86: case 87:
  392.     case 88: case 89: case 90: case 91:
  393.     case 92: case 93: case 94: case 95:
  394.       break;
  395.  
  396.     case  96: case  97: case  98: case  99:
  397.     case 100: case 101: case 102: case 103:
  398.       break;
  399.  
  400.     case 104: case 105: case 106: case 107:
  401.     case 108: case 109: case 110: case 111:
  402.       break;
  403.  
  404.     case 112:
  405.       break;
  406.  
  407.     case 113: 
  408.       break;
  409.  
  410.     case 114:
  411.       break;
  412.  
  413.     case 115:
  414.       break;
  415.  
  416.     case 116:
  417.       break;
  418.  
  419.     case 117:
  420.       break;
  421.  
  422.     case 118:
  423.       break;
  424.  
  425.     case 119:
  426.       break;
  427.  
  428.     case 120:
  429.       break;
  430.       
  431.     case 121:
  432.       break;
  433.  
  434.     case 122:
  435.       break;
  436.  
  437.     case 123:
  438.       break;
  439.       
  440.     case 124:
  441.       break;
  442.  
  443.     case 125:
  444.       break;
  445.  
  446.     case 126: case 127:
  447.       break;
  448.  
  449.     case 128:
  450.       b++;
  451.       break;
  452.  
  453.     case 129:
  454.       b++;
  455.       break;
  456.  
  457.     case 130:
  458.       b++;
  459.       break;
  460.  
  461.     case 131:
  462.       b++;
  463.       break;
  464.  
  465.     case 132:
  466.       b += 2;
  467.       break;
  468.  
  469.     case 133:
  470.       b++;
  471.       break;
  472.  
  473.     case 134:
  474.       b += 2;
  475.       break;
  476.  
  477.     case 135:
  478.       break;
  479.  
  480.     case 136:
  481.       break;
  482.  
  483.     case 137:
  484.       break;
  485.  
  486.     case 138: case 139: case 140: case 141: 
  487.     case 142: case 143:
  488.       break;
  489.  
  490.     case 144: case 145: case 146: case 147:
  491.     case 148: case 149: case 150: case 151:
  492.       break;
  493.  
  494.     case 152: case 153: case 154: case 155:
  495.     case 156: case 157: case 158: case 159:
  496.       break;
  497.  
  498.     case 160: case 161: case 162: case 163:
  499.     case 164: case 165: case 166: case 167:
  500.       b++;
  501.       break;
  502.  
  503.     case 168: case 169: case 170: case 171:
  504.       b++;
  505.       break;
  506.  
  507.     case 172: case 173: case 174: case 175:
  508.       b++;
  509.       break;
  510.  
  511.     case 176: case 177: case 178: case 179: 
  512.     case 180: case 181: case 182: case 183: 
  513.     case 184: case 185: case 186: case 187: 
  514.     case 188: case 189: case 190: case 191: 
  515.       break;
  516.  
  517.     case 192: case 193: case 194: case 195: 
  518.     case 196: case 197: case 198: case 199: 
  519.     case 200: case 201: case 202: case 203: 
  520.     case 204: case 205: case 206: case 207: 
  521.       break;
  522.  
  523.     case 208: case 209: case 210: case 211: 
  524.     case 212: case 213: case 214: case 215: 
  525.     case 216: case 217: case 218: case 219: 
  526.     case 220: case 221: case 222: case 223: 
  527.       break;
  528.  
  529.     case 224: case 225: case 226: case 227: 
  530.     case 228: case 229: case 230: case 231: 
  531.     case 232: case 233: case 234: case 235: 
  532.     case 236: case 237: case 238: case 239: 
  533.       break;
  534.  
  535.     case 240: case 241: case 242: case 243: 
  536.     case 244: case 245: case 246: case 247: 
  537.     case 248: case 249: case 250: case 251: 
  538.     case 252: case 253: case 254: case 255: 
  539.       break;
  540.  
  541.     default:
  542.       break;
  543.     }
  544.   }
  545.   printf("\n");
  546. }
  547.  
  548. void printByteCodeName(bp, ip, literalVec)
  549. Byte    bp[];
  550. int    ip;
  551. OOP    literalVec[];
  552. {
  553.   switch (bp[0]) {
  554.   case  0: case  1: case  2: case  3:
  555.   case  4: case  5: case  6: case  7:
  556.   case  8: case  9: case 10: case 11:
  557.   case 12: case 13: case 14: case 15:
  558.     printf("push Instance Variable[%d]", bp[0] & 15);
  559.     break;
  560.  
  561.   case 16: case 17: case 18: case 19:
  562.   case 20: case 21: case 22: case 23:
  563.   case 24: case 25: case 26: case 27:
  564.   case 28: case 29: case 30: case 31:
  565.     printf("push Temporary[%d]", bp[0] & 15);
  566.     break;
  567.     
  568.   case 32: case 33: case 34: case 35:
  569.   case 36: case 37: case 38: case 39:
  570.   case 40: case 41: case 42: case 43:
  571.   case 44: case 45: case 46: case 47:
  572.   case 48: case 49: case 50: case 51:
  573.   case 52: case 53: case 54: case 55:
  574.   case 56: case 57: case 58: case 59:
  575.   case 60: case 61: case 62: case 63:
  576.     printf("push Literal[%d]", bp[0] & 31);
  577.     break;
  578.     
  579.   case 64: case 65: case 66: case 67:
  580.   case 68: case 69: case 70: case 71:
  581.   case 72: case 73: case 74: case 75:
  582.   case 76: case 77: case 78: case 79:
  583.   case 80: case 81: case 82: case 83:
  584.   case 84: case 85: case 86: case 87:
  585.   case 88: case 89: case 90: case 91:
  586.   case 92: case 93: case 94: case 95:
  587.     printf("push Global Variable[%d] = ", bp[0] & 31);
  588.     printAssociationKey(literalVec[bp[0] & 31]);
  589.     break;
  590.     
  591.   case  96: case  97: case  98: case  99:
  592.   case 100: case 101: case 102: case 103:
  593.     printf("pop and store Instance Variable[%d]", bp[0] & 7);
  594.     break;
  595.     
  596.   case 104: case 105: case 106: case 107:
  597.   case 108: case 109: case 110: case 111:
  598.     printf("pop and store Temporary[%d]", bp[0] & 7);
  599.     break;
  600.     
  601.   case 112:
  602.     printf("push self");
  603.     break;
  604.     
  605.   case 113: 
  606.     printf("push true");
  607.     break;
  608.     
  609.   case 114:
  610.     printf("push false");
  611.     break;
  612.     
  613.   case 115:
  614.     printf("push nil");
  615.     break;
  616.     
  617.   case 116:
  618.     printf("push -1");
  619.     break;
  620.     
  621.   case 117:
  622.     printf("push 0");
  623.     break;
  624.     
  625.   case 118:
  626.     printf("push 1");
  627.     break;
  628.     
  629.   case 119:
  630.     printf("push 2");
  631.     break;
  632.     
  633.   case 120:
  634.     printf("return self");
  635.     break;
  636.     
  637.   case 121:
  638.     printf("return true");
  639.     break;
  640.     
  641.   case 122:
  642.     printf("return false");
  643.     break;
  644.     
  645.   case 123:
  646.     printf("return nil");
  647.     break;
  648.     
  649.   case 124:
  650.     printf("return Message stack top");
  651.     break;
  652.     
  653.   case 125:
  654.     printf("return Block stack top");
  655.     break;
  656.     
  657.   case 126: case 127:
  658.     printf("Bytecode %d ILLEGAL!!!", bp[0]);
  659.     break;
  660.     
  661.   case 128:
  662.     switch (bp[1] >> 6) {
  663.     case 0:
  664.       printf("push Instance Variable[%d]", bp[1] & 63);
  665.       break;
  666.     case 1:
  667.       printf("push Temporary[%d]", bp[1] & 63);
  668.       break;
  669.     case 2:
  670.       printf("push Constant[%d]", bp[1] & 63);
  671.       break;
  672.     case 3:
  673.       printf("push Global Variable[%d] = ", bp[1] & 63);
  674.       printAssociationKey(literalVec[bp[1] & 63]);
  675.       break;
  676.     }
  677.     break;
  678.     
  679.   case 129:
  680.     switch (bp[1] >> 6) {
  681.     case 0:
  682.       printf("store Instance Variable[%d]", bp[1] & 63);
  683.       break;
  684.     case 1:
  685.       printf("store Temporary[%d]", bp[1] & 63);
  686.       break;
  687.     case 2:
  688.       printf("Illegal store into constant[%d]", bp[1] & 63);
  689.       break;
  690.     case 3:
  691.       printf("store Global Variable[%d] = ", bp[1] & 63);
  692.       printAssociationKey(literalVec[bp[1] & 63]);
  693.       break;
  694.     }
  695.     break;
  696.     
  697.   case 130:
  698.     switch (bp[1] >> 6) {
  699.     case 0:
  700.       printf("pop and store Instance Variable[%d]", bp[1] & 63);
  701.       break;
  702.     case 1:
  703.       printf("pop and store Temporary[%d]", bp[1] & 63);
  704.       break;
  705.     case 2:
  706.       printf("lllegal pop and store into constant[%d]", bp[1] & 63);
  707.       break;
  708.     case 3:
  709.       printf("pop and store Global Variable[%d]", bp[1] & 63);
  710.       printAssociationKey(literalVec[bp[1] & 63]);
  711.       break;
  712.     }
  713.     break;
  714.     
  715.   case 131:
  716.     printf("send selector %d, %d args = ", bp[1] & 31, bp[1] >> 5);
  717.     printSymbol(literalVec[bp[1] & 31]);
  718.     break;
  719.     
  720.   case 132:
  721.     printf("send selector %d, %d args = ", bp[2], bp[1]);
  722.     printSymbol(literalVec[bp[2]]);
  723.     break;
  724.     
  725.   case 133:
  726.     printf("send to super selector %d, %d args = ", bp[1] & 31, bp[1] >> 5);
  727.     printSymbol(literalVec[bp[1] & 31]);
  728.     break;
  729.     
  730.   case 134:
  731.     printf("send to super selector %d, %d args = ", bp[2], bp[1]);
  732.     printSymbol(literalVec[bp[2]]);
  733.     break;
  734.     
  735.   case 135:
  736.     printf("pop stack top");
  737.     break;
  738.     
  739.   case 136:
  740.     printf("duplicate stack top");
  741.     break;
  742.     
  743.     
  744.   case 137:
  745.     printf("push current context");
  746.     break;
  747.     
  748.   case 138: case 139: case 140: case 141: 
  749.   case 142: case 143:
  750.     printf("Illegal bytecode %d!!!", bp[0]);
  751.     break;
  752.     
  753.   case 144: case 145: case 146: case 147:
  754.   case 148: case 149: case 150: case 151:
  755.     printf("jump to %d", (bp[0] & 7) + ip + 1 + 1);
  756.     break;
  757.     
  758.   case 152: case 153: case 154: case 155:
  759.   case 156: case 157: case 158: case 159:
  760.     printf("jump to %d if false", (bp[0] & 7) + ip + 1 + 1);
  761.     break;
  762.     
  763.   case 160: case 161: case 162: case 163:
  764.   case 164: case 165: case 166: case 167:
  765.     printf("jump to %d", ((bp[0]&7)-4) * 256 + bp[1] + ip + 2);
  766.     break;
  767.     
  768.   case 168: case 169: case 170: case 171:
  769.     printf("pop and jump to %d if true", (bp[0]&3) * 256 + bp[1] + ip + 2);
  770.     break;
  771.     
  772.   case 172: case 173: case 174: case 175:
  773.     printf("pop and jump to %d if false", (bp[0]&3) * 256 + bp[1] + ip + 2);
  774.     break;
  775.     
  776.   case 176: case 177: case 178: case 179: 
  777.   case 180: case 181: case 182: case 183: 
  778.   case 184: case 185: case 186: case 187: 
  779.   case 188: case 189: case 190: case 191: 
  780.     printf("send arithmetic message \"%s\"", mathMessageName[bp[0] & 15]);
  781.     break;
  782.     
  783.   case 192: case 193: case 194: case 195: 
  784.   case 196: case 197: case 198: case 199: 
  785.   case 200: case 201: case 202: case 203: 
  786.   case 204: case 205: case 206: case 207: 
  787.     printf("send special message \"%s\"", specialMessageName[bp[0] & 15]);
  788.     break;
  789.     
  790.   case 208: case 209: case 210: case 211: 
  791.   case 212: case 213: case 214: case 215: 
  792.   case 216: case 217: case 218: case 219: 
  793.   case 220: case 221: case 222: case 223: 
  794.     printf("send selector %d, 0 args = ", bp[0] & 15);
  795.     printSymbol(literalVec[bp[0] & 15]);
  796.     break;
  797.     
  798.   case 224: case 225: case 226: case 227: 
  799.   case 228: case 229: case 230: case 231: 
  800.   case 232: case 233: case 234: case 235: 
  801.   case 236: case 237: case 238: case 239: 
  802.     printf("send selector %d, 1 arg = ", bp[0] & 15);
  803.     printSymbol(literalVec[bp[0] & 15]);
  804.     break;
  805.     
  806.   case 240: case 241: case 242: case 243: 
  807.   case 244: case 245: case 246: case 247: 
  808.   case 248: case 249: case 250: case 251: 
  809.   case 252: case 253: case 254: case 255: 
  810.     printf("send selector %d, 2 args = ", bp[0] & 15);
  811.     printSymbol(literalVec[bp[0] & 15]);
  812.     break;
  813.     
  814.   default:
  815.     printf("UNHANDLED BYTE CODE %d!!!", bp[0]);
  816.     break;
  817.   }
  818. }
  819.